//------------------------------------------------------------------------------
//
//  progbar.cpp
//
//  Copyright (C) 2007 Visual.Wei
//  Author: Wei Shuai <cpuwolf@sina.com>
//
//  
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
//

#include <windows.h>
#include <winioctl.h>
#include <aygshell.h>
#include <commctrl.h>
#include <pm.h>
#include <psapi.h>
#include "resource.h"
#include <pkfuncs.h>
#include "progbar.h"
#include "AppleList.h"
#include "PMTabCtrl.h"
#include "PMListView.h"
#include "PMSplitCtrl.h"
#include "s3c2443.h"
#include "DeviceInterface.h"
#include "PUMeasure.h"



static INT_PTR CALLBACK DialogProcPower(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam);
static INT_PTR CALLBACK DialogProcInfo(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam);
static INT_PTR CALLBACK DialogProcModule(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam);
static INT_PTR CALLBACK DialogProcModInfo(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam);
static INT_PTR CALLBACK DialogProcInterface(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam);
static INT_PTR CALLBACK DialogProcDevMgr(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam);

DBGPARAM dpCurSettings;

// define guids
GUID idGenericPMDeviceClass = { 0xA32942B7, 0x920C, 0x486b, { 0xB0, 0xE6, 0x92, 0xA7, 0x02, 0xA9, 0x9B, 0x35 } };
GUID idPMDisplayDeviceClass = { 0xEB91C7C9, 0x8BF6, 0x4A2D, { 0x9A, 0xB8, 0x69, 0x72, 0x4E, 0xED, 0x97, 0xD1 } };

HINSTANCE	g_hInst;

struct TabPage
{
	LPTSTR lpcaption;
	int len;
	LPCTSTR lpResource;
	DLGPROC DialogProc;
	struct TabPage * next;
};


struct TabPage TP_DisplayDev[]=
{
	{_T("PowerState"),16,MAKEINTRESOURCE(IDD_DIALOG1),DialogProcPower,NULL}
};
struct TabPage TP_StreamDev[]=
{
	{_T("Power"),16,MAKEINTRESOURCE(IDD_DIALOG1),DialogProcPower,NULL},
	{_T("Info"),16,MAKEINTRESOURCE(IDD_DIALOGINFO),DialogProcInfo,NULL},
	{_T("DLL"),16,MAKEINTRESOURCE(IDD_DIALOG3),DialogProcModule,NULL},
	{_T("DLL Info"),16,MAKEINTRESOURCE(IDD_DIALOGMODINFO),DialogProcModInfo,NULL},
	{_T("DevMgr"),16,MAKEINTRESOURCE(IDD_DEVMGR),DialogProcDevMgr,NULL}
	
};
struct TabPage TP_Interface[]=
{
	{_T("IClass"),16,MAKEINTRESOURCE(IDD_DIALOGCLASS),DialogProcInterface,NULL},
};




void inline TabPageInit(struct TabPage parray[],int num)
{
	int i;
	for(i=0;i<(num-1);i++)
		parray[i].next=parray+i+1;
}




struct  CEDevice * g_pCurDevice=NULL;



class PMTaskBar
{

public:
	HWND g_hwnd;
	RECT rect;
	PMTaskBar();
	~PMTaskBar();
};

PMSplitCtrl * p_pmsplit;
PMListView *p_pmlv;
PMTabCtrl * p_pmtc;
HIMAGELIST g_ImgList;
PMTaskBar *g_taskbar;
HWND g_hWndMenuBar;		// menu bar handle
HWND g_hwndCB;

// prototypes for device driver entry points
typedef DWORD (* pInitFn)(DWORD,LPVOID);
typedef BOOL (* pPreDeinitFn)(DWORD);
typedef BOOL (* pDeinitFn)(DWORD);
typedef BOOL (* pOpenFn)(DWORD,DWORD,DWORD);
typedef BOOL (* pPreCloseFn)(DWORD);
typedef BOOL (* pCloseFn)(DWORD);
typedef DWORD (* pReadFn)(DWORD,LPVOID,DWORD);
typedef DWORD (* pWriteFn)(DWORD,LPCVOID,DWORD);
typedef DWORD (* pSeekFn)(DWORD,long,DWORD);
typedef BOOL (* pControlFn)(DWORD,DWORD,PBYTE,DWORD,PBYTE,DWORD,PDWORD);
typedef void (* pPowerupFn)(DWORD);
typedef void (* pPowerdnFn)(DWORD);

class PMModule
{
private:
	LPVOID GetDMProcAddr(TCHAR *,TCHAR *);
	
public:
	// driver entry points
    pInitFn fnInit;             // required
    pPreDeinitFn fnPreDeinit;   // optional
    pDeinitFn fnDeinit;         // required
    pOpenFn fnOpen;             // if present, need close and at least one of read/write/seek/control
    pPreCloseFn fnPreClose;     // optional even if close is present
    pCloseFn fnClose;           // required if open is present
    pReadFn fnRead;
    pWriteFn fnWrite;
    pSeekFn fnSeek;
    pControlFn fnControl;
    pPowerupFn fnPowerup;       // optional, can be NULL
    pPowerdnFn fnPowerdn;       // optional, can be NULL
	HMODULE hmodule;
	//functions
	PMModule(TCHAR * DevName,TCHAR * ModuleName);
	~PMModule();
	BOOL GetModuleInfo(LPMODULEINFO lpmodinfo);
};

BOOL GetDeviceModuleName(TCHAR * szDeviceKey,TCHAR * ModuleName,DWORD len)
{
	HKEY hk;
	DWORD dwStatus,cbVal=len,dwType;
	BOOL ret=FALSE;

	dwStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szDeviceKey, 0, 0, &hk);
	if(dwStatus == ERROR_SUCCESS) 
	{
		dwType=REG_SZ;
		if(ModuleName)
		{
			dwStatus=RegQueryValueEx(hk,_T("Dll"),NULL,&dwType,(LPBYTE)ModuleName,&cbVal);
			if(dwStatus == ERROR_SUCCESS) 
			{
				ret=TRUE;
			}
		}
		RegCloseKey(hk);
	}
	return ret;
}


static INT_PTR CALLBACK DialogProcPower(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
	TCHAR txt[512];
	CEDevice * pdev=g_pCurDevice;
	HANDLE hdevice;
	//POWER_RELATIONSHIP pr;
	CEDEVICE_POWER_STATE state=PwrDeviceUnspecified;
	POWER_CAPABILITIES reqDx;
	DWORD dwBytesReturned;
	HWND hwnd;
	BOOL isok=TRUE;
	static struct MsgMap
	{
		CEDEVICE_POWER_STATE power;
		int id;
	}maptable[]={{D0,IDC_RADIO1},{D1,IDC_RADIO2},
		{D2,IDC_RADIO3},{D3,IDC_RADIO4},{D4,IDC_RADIO5}};
		

	switch(uMsg)
	{
		case WM_INITDIALOG:
			if(pdev)
			{
				hdevice=pdev->popt->Open(pdev->info.szLegacyName);
				if(hdevice==INVALID_HANDLE_VALUE)
				{
					wsprintf(txt,_T("!open error"));
					SetDlgItemText(hwndDlg,IDC_STATIC_INFO,txt);
					ShowWindow(GetDlgItem(hwndDlg,IDC_STATIC_INFO),SW_SHOW);
					isok=FALSE;
					break;
				}
				if(!pdev->popt->Request(hdevice, IOCTL_POWER_CAPABILITIES , NULL, 
					0, &reqDx, sizeof(reqDx), &dwBytesReturned))
				{
					wsprintf(txt,_T("!cap error"));
					SetDlgItemText(hwndDlg,IDC_STATIC_INFO,txt);
					ShowWindow(GetDlgItem(hwndDlg,IDC_STATIC_INFO),SW_SHOW);
					isok=FALSE;
					break;
				}
				if(!pdev->popt->Request(hdevice, IOCTL_POWER_GET , NULL, 
					0, &state, sizeof(state), &dwBytesReturned))
				{
					if(dwBytesReturned!=sizeof(state))
					{
						wsprintf(txt,_T("!get error %d"),GetLastError());
						SetDlgItemText(hwndDlg,IDC_STATIC_INFO,txt);
						ShowWindow(GetDlgItem(hwndDlg,IDC_STATIC_INFO),SW_SHOW);
						isok=FALSE;
					}
				}
				pdev->popt->Close(hdevice);

				p_pmtc->SetPage(0,isok);
				//if(!isok)
				//	ShowWindow(GetDlgItem(hwndDlg,IDC_STATIC_INFO),SW_SHOW);

				for(int i=0;i<sizeof(maptable)/sizeof(maptable[0]);i++)
				{
					hwnd=GetDlgItem(hwndDlg,maptable[i].id);
					if(reqDx.DeviceDx&DX_MASK(maptable[i].power))
						EnableWindow(hwnd,TRUE);
					else
						EnableWindow(hwnd,FALSE);

					if(maptable[i].power==state)
						CheckRadioButton(hwndDlg,maptable[0].id,maptable[4].id,maptable[i].id);
				}

			}
			break;
		case WM_COMMAND:
			switch(HIWORD(wParam))
			{
				case BN_CLICKED:
				for(int i=0;i<sizeof(maptable)/sizeof(maptable[0]);i++)
				{
					if(lParam==(LPARAM)GetDlgItem(hwndDlg,maptable[i].id))
					{
							if(pdev)
							{
								if(IsDlgButtonChecked(hwndDlg,IDC_CHECKMGR))
								{
									SetDevicePower(pdev->info.szLegacyName,POWER_NAME,maptable[i].power);
								}
								else
								{
									hdevice=pdev->popt->Open(pdev->info.szLegacyName);
									if(hdevice==INVALID_HANDLE_VALUE)
									{
										wsprintf(txt,_T("!oerror"));
										SetDlgItemText(hwndDlg,IDC_RADIO1,txt);
										break;
									}
									state=maptable[i].power;
									if(!pdev->popt->Request(hdevice, IOCTL_POWER_SET , NULL, 
										0, &state, sizeof(state), &dwBytesReturned))
									{
										if(dwBytesReturned!=sizeof(state))
										{
											wsprintf(txt,_T("!serror"));
											SetDlgItemText(hwndDlg,IDC_RADIO1,txt);
										}
									}
									pdev->popt->Close(hdevice);
								}
							}
					}
				}
			}
			break;
	}		
	return FALSE;
}
static INT_PTR CALLBACK DialogProcInfo(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
	TCHAR txt[512];
	CEDevice * pdev=g_pCurDevice;

	switch(uMsg)
	{
		case WM_INITDIALOG:
			if(pdev)
			{
				wsprintf(txt,_T("%s"),pdev->info.szLegacyName);
				SetDlgItemText(hwndDlg,IDC_STATIC_NAME1,txt);
				wsprintf(txt,_T("%s"),pdev->info.szDeviceName);
				SetDlgItemText(hwndDlg,IDC_STATIC_NAME2,txt);
				wsprintf(txt,_T("%s"),pdev->info.szBusName);
				SetDlgItemText(hwndDlg,IDC_STATIC_NAME3,txt);
				wsprintf(txt,_T("%s"),pdev->info.szDeviceKey);
				SetDlgItemText(hwndDlg,IDC_STATIC_NAME4,txt);
			}

			
			break;
	}		
	return FALSE;
}

#define DEVFLAGS_NOLOAD 0x00000004//Driver is not loaded.
 
static DWORD DeviceDriverFlags(LPCWSTR szKeyPath, DWORD flags,BOOL blset=TRUE)
{
    BOOL rc = 0;
    HKEY hKey;
    DWORD value;
	DWORD type=REG_DWORD,ret;
	DWORD val;

    // Open/create key
    if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, szKeyPath, 0, NULL, 0, 0, NULL,
         &hKey, &value) != ERROR_SUCCESS) 
		 goto cleanUp;

    // Get value
    rc = RegQueryValueEx (
        hKey, L"Flags", 0, &type, (UCHAR*)&val, &ret
    ) == ERROR_SUCCESS;

	if(!flags)
	{
		rc=val;
		goto cls;
	}

	//check
	if(blset)
	{
		val|=flags;
	}
	else
	{
		val&=(~flags);
	}

    // Set value
    rc = RegSetValueEx(
        hKey, L"Flags", 0, REG_DWORD, (UCHAR*)&val, sizeof(DWORD)
    ) == ERROR_SUCCESS;

	RegFlushKey(hKey);
cls:
    // Close key
    RegCloseKey(hKey);

cleanUp:
    return rc;
}

static BOOL DelDeviceDriver(LPCWSTR szKeyPath)
{
    BOOL rc = 0;
    HKEY hKey;
    DWORD value;


    // Open/create key
    if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, szKeyPath, 0, NULL, 0, 0, NULL,
         &hKey, &value) != ERROR_SUCCESS) 
		 goto cleanUp;

    // Delete value
	RegDeleteKey(hKey,szKeyPath);

	RegFlushKey(hKey);

    // Close key
    RegCloseKey(hKey);

cleanUp:
    return rc;
}


static INT_PTR CALLBACK DialogProcDevMgr(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
	TCHAR txt[512];
	CEDevice * pdev=g_pCurDevice;

	switch(uMsg)
	{
		case WM_INITDIALOG:
			SendMessage(GetDlgItem(hwndDlg,IDC_COMBOBOOTTYPE),(UINT) CB_ADDSTRING,0,(LPARAM)_T("Enable"));  
			SendMessage(GetDlgItem(hwndDlg,IDC_COMBOBOOTTYPE),(UINT) CB_ADDSTRING,0,(LPARAM)_T("Disable")); 
			if(pdev)
			{
				if(DeviceDriverFlags(pdev->info.szDeviceKey,0)&DEVFLAGS_NOLOAD)
				{
					SendMessage(GetDlgItem(hwndDlg,IDC_COMBOBOOTTYPE),(UINT) CB_SETCURSEL,1,0);
				}
				else
					SendMessage(GetDlgItem(hwndDlg,IDC_COMBOBOOTTYPE),(UINT) CB_SETCURSEL,0,0);
			}
			break;
        case WM_COMMAND:
			if(LOWORD(wParam) == IDC_BUTTONPD  )
			{
				if (HIWORD(wParam)==BN_CLICKED)
				{
					if(pdev)
					{
						if(DeactivateDevice(pdev->info.hDevice))
						{
							EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTONPD),FALSE);
						}
						else
							MessageBox(0, txt,_T("Error"),MB_ICONEXCLAMATION|MB_TOPMOST);
					}
					return TRUE;
				}
			}
/*
			else if(LOWORD(wParam)==IDC_COMBOBOOTTYPE)
			{
				if (HIWORD(wParam)==CBN_SELCHANGE)
				{
					MessageBox(0, _T("sel"),_T("sel"),MB_ICONEXCLAMATION|MB_TOPMOST);
				}
			}
*/
			else if(LOWORD(wParam)==IDC_BUTTONSET)
			{
				if(IsDlgButtonChecked(hwndDlg,IDC_RADIOBOOT)==BST_CHECKED)
				{
					if(pdev)
					{
						switch(SendMessage(GetDlgItem(hwndDlg,IDC_COMBOBOOTTYPE),(UINT) CB_GETCURSEL,0,0))
						{
						case 0:
							//MessageBox(0, _T("0"),_T("sel"),MB_ICONEXCLAMATION|MB_TOPMOST);
							DeviceDriverFlags(pdev->info.szDeviceKey,DEVFLAGS_NOLOAD,FALSE);
							break;
						case 1:
							//MessageBox(0, _T("1"),_T("sel"),MB_ICONEXCLAMATION|MB_TOPMOST);
							DeviceDriverFlags(pdev->info.szDeviceKey,DEVFLAGS_NOLOAD);
							MessageBox(0, _T("It will apply at the next boot"),_T("select"),MB_ICONEXCLAMATION|MB_TOPMOST);
							break;
						}
					}
				}
				else if(IsDlgButtonChecked(hwndDlg,IDC_RADIODEL)==BST_CHECKED)
				{
					if(pdev)
					{
						//dont load the driver at next boot
						DelDeviceDriver(pdev->info.szDeviceKey);
						MessageBox(0, _T("It will apply at the next boot"),_T("select"),MB_ICONEXCLAMATION|MB_TOPMOST);
					}
				}
			}

            break;
	}		
	return FALSE;
}
static INT_PTR CALLBACK DialogProcInterface(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
	TCHAR txt[512];
	CEDevice * pdev=g_pCurDevice;
	LPGUID pClass;

	switch(uMsg)
	{
		case WM_INITDIALOG:
			if(pdev)
			{
				pClass=&pdev->guid;
				if(pClass)
				{
					wsprintf(txt,_T("%08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X\r\n"), 
						pClass->Data1, pClass->Data2, pClass->Data3,
						(pClass->Data4[0] << 8) + pClass->Data4[1], pClass->Data4[2], pClass->Data4[3], 
						pClass->Data4[4], pClass->Data4[5], pClass->Data4[6], pClass->Data4[7]);

					SetDlgItemText(hwndDlg,IDC_STATIC_ICLASSNAME,txt);
				}

			}

			
			break;
	}		
	return FALSE;
}
static INT_PTR CALLBACK DialogProcModInfo(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
	TCHAR txt[512];
	CEDevice * pdev=g_pCurDevice;
	static PMModule * pmod=NULL;
	MODULEINFO info;

	switch(uMsg)
	{
		case WM_INITDIALOG:
			if(pdev)
			{
				memset(txt,0,sizeof(txt));
				GetDeviceModuleName(pdev->info.szDeviceKey,txt,sizeof(txt));
				wsprintf(txt,_T("%s"),txt);
				SetDlgItemText(hwndDlg,IDC_STATIC_MODULE1,txt);
				pmod=new PMModule(pdev->info.szLegacyName,txt);
				if(pmod)
				{
					if(pmod->hmodule)
					{
						ShowWindow(GetDlgItem(hwndDlg,IDC_STATIC_MODI),SW_SHOW);
						pmod->GetModuleInfo(&info);
						wsprintf(txt,_T("Base : 0x%08X"),info.lpBaseOfDll);
						SetDlgItemText(hwndDlg,IDC_STATIC_MODINFO1,txt);
						wsprintf(txt,_T("Size : 0x%08X (B)"),info.SizeOfImage);
						SetDlgItemText(hwndDlg,IDC_STATIC_MODINFO2,txt);
						wsprintf(txt,_T("Entry: 0x%08X"),info.EntryPoint);
						SetDlgItemText(hwndDlg,IDC_STATIC_MODINFO3,txt);
					}
				}
			}
			break;
		case WM_CLOSE:
			if(pmod)
				delete pmod;
			break;
	}		
	return FALSE;
}
static INT_PTR CALLBACK DialogProcModule(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
	TCHAR txt[512];
	CEDevice * pdev=g_pCurDevice;
	static PMModule * pmod=NULL;

	switch(uMsg)
	{
		case WM_INITDIALOG:
			if(pdev)
			{
				memset(txt,0,sizeof(txt));
				GetDeviceModuleName(pdev->info.szDeviceKey,txt,sizeof(txt));
				wsprintf(txt,_T("%s"),txt);
				SetDlgItemText(hwndDlg,IDC_STATIC_MODULE1,txt);
				pmod=new PMModule(pdev->info.szLegacyName,txt);
				if(pmod)
				{
					if(pmod->hmodule)
					{
						ShowWindow(GetDlgItem(hwndDlg,IDC_STATIC_MODI),SW_SHOW);
						if(pmod->fnPowerup)
							EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTONPU),TRUE);
						if(pmod->fnPowerdn)
							EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTONPD),TRUE);
						if(pmod->fnRead)
							EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTONRD),TRUE);
						if(pmod->fnWrite)
							EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTONWR),TRUE);
						if(pmod->fnPreClose)
							EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTONPC),TRUE);
						if(pmod->fnSeek)
							EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTONSK),TRUE);
					}
				}
			}
			break;
        case WM_COMMAND:
			if((HIWORD(wParam)==BN_CLICKED)&&(pmod))
			{
				if (LOWORD(wParam) == IDC_BUTTONPU)
				{
					//MessageBox(0,_T("button"),_T("mod"),MB_OK|MB_TOPMOST);
					pmod->fnPowerup(0);
					return TRUE;
				}
				else if (LOWORD(wParam) == IDC_BUTTONPD)
				{
					pmod->fnPowerdn(0);
				}
			}
            break;
		case WM_CLOSE:
			if(pmod)
				delete pmod;
			break;
	}		
	return FALSE;
}

static INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        case WM_INITDIALOG:
#if 1		
            {
                // Create a Done button and size it.  
                SHINITDLGINFO shidi;
                shidi.dwMask = SHIDIM_FLAGS;
                shidi.dwFlags = SHIDIF_FULLSCREENNOMENUBAR;
                shidi.hDlg = hDlg;
                SHInitDialog(&shidi);
            }
#endif
            return (INT_PTR)TRUE;

        case WM_COMMAND:
            if (LOWORD(wParam) == IDOK)
            {
                EndDialog(hDlg, LOWORD(wParam));
                return TRUE;
            }
            break;

        case WM_CLOSE:
            EndDialog(hDlg, message);
            return TRUE;

    }
    return (INT_PTR)FALSE;
}

//Visual: draw custom button
static void SysBtnDraw(HBITMAP memBM,HIMAGELIST sys_ImgList,LPDRAWITEMSTRUCT lpdis,int imgindex)
{
	RECT rec;
	TCHAR txt[50];
	HDC hdcMem;

	CopyRect(&rec,&lpdis->rcItem);
	hdcMem = CreateCompatibleDC(lpdis->hDC); 
	
	SelectObject ( hdcMem, memBM );

	//prepare background
	FillRect(hdcMem,&lpdis->rcItem,GetSysColorBrush (COLOR_WINDOW));

	if (lpdis->itemState & ODS_SELECTED)
	{
		HPEN hpen,holdpen;
		HBRUSH hbru,holdbru;
		hpen=CreatePen(PS_SOLID,0,RGB(128,128,255));
		hbru=CreateSolidBrush(RGB(210,210,255));
		holdpen=(HPEN)SelectObject(hdcMem,hpen);
		holdbru=(HBRUSH)SelectObject(hdcMem,hbru);
		RoundRect(hdcMem,0,0,rec.right,rec.bottom,8,8);
		SelectObject(hdcMem,holdpen);
		SelectObject(hdcMem,holdbru);
		DeleteObject(hpen);
		DeleteObject(hbru);
		SetBkColor(hdcMem,RGB(210,210,255));
	}
	else
	{
		SetBkColor(hdcMem,GetSysColor(COLOR_WINDOW));
	}

	rec.left+=(48+5);

	//get button text
	GetWindowText(lpdis->hwndItem,txt,50);
	DrawText(hdcMem,
		txt,lstrlen(txt),
		&rec,DT_VCENTER|DT_LEFT|DT_SINGLELINE);

	ImageList_DrawEx(sys_ImgList,imgindex,hdcMem,
		2,2,0,0,
		CLR_DEFAULT,CLR_NONE,
		 ILD_NORMAL   );

	//update
	BitBlt(lpdis->hDC, 
               lpdis->rcItem.left,lpdis->rcItem.top, 
               lpdis->rcItem.right-lpdis->rcItem.left, lpdis->rcItem.bottom-lpdis->rcItem.top, 
               hdcMem, 
               0,0, 
               SRCCOPY);
	//release
	DeleteDC(hdcMem); 

}
static INT_PTR CALLBACK DialogProcSystem(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	LPDRAWITEMSTRUCT lpdis; 
	static HIMAGELIST sys_ImgList;
	HDC hdc;
	static HBITMAP memBM;

    switch (message)
    {
        case WM_INITDIALOG:	
            {
                // Create a Done button and size it.  
                SHINITDLGINFO shidi;
                shidi.dwMask = SHIDIM_FLAGS;
                shidi.dwFlags = SHIDIF_FULLSCREENNOMENUBAR;
                shidi.hDlg = hDlg;
                SHInitDialog(&shidi);
            }
			//create
			sys_ImgList=ImageList_Create(48,48,ILC_COLOR32|ILC_MASK,10,0);
			ImageList_AddIcon(sys_ImgList,LoadIcon(g_hInst,MAKEINTRESOURCE(IDI_ICONREBOOT)));
			ImageList_AddIcon(sys_ImgList,LoadIcon(g_hInst,MAKEINTRESOURCE(IDI_ICONSTANDBY)));
			ImageList_AddIcon(sys_ImgList,LoadIcon(g_hInst,MAKEINTRESOURCE(IDI_ICONSHUTDOWN)));
			ImageList_AddIcon(sys_ImgList,LoadIcon(g_hInst,MAKEINTRESOURCE(IDI_ICONLOW)));

			hdc=GetDC(hDlg);
			memBM = CreateCompatibleBitmap (hdc,200,100);
			ReleaseDC(hDlg,hdc);
            return (INT_PTR)TRUE;
		
		//case WM_SIZE:
		//	RelayoutDialog(g_hInst, hDlg, 1 ?
		//		MAKEINTRESOURCE(IDD_SYSTEMBOX) :MAKEINTRESOURCE(IDD_SYSTEMBOX_WIDE));

		//	break;
		//custom draw
		case WM_DRAWITEM: 
			lpdis = (LPDRAWITEMSTRUCT) lParam; 

			switch(lpdis->CtlID)
			{
			case IDB_BUTTON_REBOOT:
				SysBtnDraw(memBM,sys_ImgList,lpdis,0);
				break;
			case IDB_BUTTON_STANDBY:
				SysBtnDraw(memBM,sys_ImgList,lpdis,1);
				break;
			case IDB_BUTTON_SHUTDOWN:
				SysBtnDraw(memBM,sys_ImgList,lpdis,2);
				break;
			case IDB_BUTTON_LOW:
				SysBtnDraw(memBM,sys_ImgList,lpdis,3);
				break;
			}

			break;
        case WM_COMMAND:
            switch(LOWORD(wParam))
            {
			case IDOK:
				//delete
				ImageList_Destroy(sys_ImgList);
				DeleteObject(memBM);
				EndDialog(hDlg, LOWORD(wParam));
				break;
			case IDB_BUTTON_REBOOT:
                SetSystemPowerState(NULL,POWER_STATE_RESET,POWER_FORCE);
                return TRUE;
			case IDB_BUTTON_SHUTDOWN:
                SetSystemPowerState(NULL,POWER_STATE_OFF,POWER_FORCE);
                return TRUE;
			case IDB_BUTTON_STANDBY:
                SetSystemPowerState(NULL,POWER_STATE_SUSPEND,POWER_FORCE);
                return TRUE;
			case IDB_BUTTON_LOW:
                SetSystemPowerState(NULL,POWER_STATE_CRITICAL,POWER_FORCE);
                return TRUE;
            }
            break;

        case WM_CLOSE:
            EndDialog(hDlg, message);
            return TRUE;

    }
    return (INT_PTR)FALSE;
}
//-----------------------------------------------------------------------
#define IOCTL_HAL_CPU_SLOW	CTL_CODE(FILE_DEVICE_HAL, 5090, METHOD_BUFFERED, FILE_ANY_ACCESS)
static INT_PTR CALLBACK DialogProcIR(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	LPDRAWITEMSTRUCT lpdis; 
	static HIMAGELIST sys_ImgList;
	static BOOL bnstate[1];
	static volatile S3C2443_IOPORT_REG * io_space;
	BOOL slow=FALSE;
	DWORD dwret;
	UINT chk;
	typedef BOOL (*GETADDRFN)();
	static HINSTANCE hCoreDll;
	static GETADDRFN pfnGetAddr=NULL;

    switch (message)
    {
        case WM_INITDIALOG:	
            {
                // Create a Done button and size it.  
                SHINITDLGINFO shidi;
                shidi.dwMask = SHIDIM_FLAGS;
                shidi.dwFlags = SHIDIF_FULLSCREENNOMENUBAR;
                shidi.hDlg = hDlg;
                SHInitDialog(&shidi);
            }
			//create
			sys_ImgList=ImageList_Create(128,128,ILC_COLOR32|ILC_MASK,10,0);
			ImageList_AddIcon(sys_ImgList,LoadIcon(g_hInst,MAKEINTRESOURCE(IDI_IRON)));
			ImageList_AddIcon(sys_ImgList,LoadIcon(g_hInst,MAKEINTRESOURCE(IDI_IROFF)));
			//
			io_space =(S3C2443_IOPORT_REG*)VirtualAlloc( 0, sizeof(S3C2443_IOPORT_REG), MEM_RESERVE, PAGE_NOACCESS );
			VirtualCopy( (LPVOID)io_space, (LPVOID)(0x56000000 >> 8),sizeof(S3C2443_IOPORT_REG), PAGE_PHYSICAL|PAGE_READWRITE|PAGE_NOCACHE );

			if((io_space->GPBCON&(3<<4))==(2<<4))
				*bnstate=TRUE;
			else
				*bnstate=FALSE;

			//GPH12
			if((io_space->GPHDAT&(1<<12))==(1<<12))
			{
				CheckDlgButton(hDlg,IDC_DVS,BST_CHECKED);
				
			}
			else
			{
				CheckDlgButton(hDlg,IDC_DVS,BST_UNCHECKED);
				
			}
			//load library
			hCoreDll = LoadLibrary(TEXT("ceddk.dll"));
			if(hCoreDll)
			{
				pfnGetAddr = (GETADDRFN)GetProcAddress(hCoreDll, TEXT("IsCPUSlowMode"));
				if(!pfnGetAddr)
				{
					MessageBox(hDlg,_T("cannot find IsCPUSlowMode()"),_T("error"),MB_ICONEXCLAMATION|MB_TOPMOST);
				}
			}
			else
				MessageBox(hDlg,_T("load ceddk.dll error"),_T("error"),MB_ICONEXCLAMATION|MB_TOPMOST);
			//
			if(pfnGetAddr)
			{
				if(pfnGetAddr())
					CheckDlgButton(hDlg,IDC_DVSEN,BST_CHECKED);
				else
					CheckDlgButton(hDlg,IDC_DVSEN,BST_UNCHECKED);
			}
            return (INT_PTR)TRUE;
		
		case WM_DRAWITEM: 
			lpdis = (LPDRAWITEMSTRUCT) lParam; 

			switch(lpdis->CtlID)
			{
			case IDB_BUTTON_IR:
					FillRect(lpdis->hDC,&lpdis->rcItem,GetSysColorBrush (COLOR_WINDOW));
					if (lpdis->itemState&ODS_SELECTED)
					{
						if(*bnstate)
							*bnstate=FALSE;
						else
							*bnstate=TRUE;
					}
					if(*bnstate)
					{
						ImageList_DrawEx(sys_ImgList,0,lpdis->hDC,
								0,0,0,0,
								CLR_DEFAULT,CLR_NONE,
								 ILD_NORMAL   );
					}
					else
					{
						ImageList_DrawEx(sys_ImgList,1,lpdis->hDC,
								0,0,0,0,
								CLR_DEFAULT,CLR_NONE,
								 ILD_NORMAL   );

					}
				break;
			}

			break;
        case WM_COMMAND:
            switch(LOWORD(wParam))
            {
			case IDOK:
				//delete
				VirtualFree((LPVOID) io_space, 0, MEM_RELEASE );
				ImageList_Destroy(sys_ImgList);
				EndDialog(hDlg, LOWORD(wParam));
				break;
			case IDB_BUTTON_IR:
				if(*bnstate)
				{
					io_space->GPBCON&=(~(3<<4));
					io_space->GPBCON|=((2<<4));
				}
				else
				{
					io_space->GPBCON&=(~(3<<4));
					io_space->GPBCON|=((1<<4));
					io_space->GPBDAT&=(~(1<<2));

				}
                return TRUE;
			case IDC_DVS:
				chk=IsDlgButtonChecked(hDlg,IDC_DVS);
				if(BST_CHECKED==chk)
				{
					io_space->GPHDAT|=(1<<12);
				}
				else if(BST_UNCHECKED==chk)
				{
					io_space->GPHDAT&=(~(1<<12));
				}
				return TRUE;
			case IDC_DVSEN:
				chk=IsDlgButtonChecked(hDlg,IDC_DVSEN);
				if(BST_CHECKED==chk)
				{
					slow=TRUE;
				}
				else if(BST_UNCHECKED==chk)
				{
					slow=FALSE;
				}
				KernelIoControl(IOCTL_HAL_CPU_SLOW,  &slow, sizeof(slow),NULL, 0,&dwret);
				return TRUE;
            }
            break;

        case WM_DESTROY:
			if (hCoreDll)
			{
				FreeLibrary(hCoreDll);
			}
            EndDialog(hDlg, message);
            return TRUE;

    }
    return (INT_PTR)FALSE;
}
//------------------------------------------------------------------------
//------------------------------------------------------------------------
//Visual: draw custom button
static void ClkBtnDraw(HBITMAP memBM,LPDRAWITEMSTRUCT lpdis,BOOL *plState)
{
	RECT rec;
	TCHAR txt[50];
	HDC hdcMem;

	CopyRect(&rec,&lpdis->rcItem);
	hdcMem = CreateCompatibleDC(lpdis->hDC); 
	
	SelectObject ( hdcMem, memBM );

	//prepare background
	FillRect(hdcMem,&lpdis->rcItem,GetSysColorBrush (COLOR_WINDOW));

	if (lpdis->itemState&ODS_SELECTED)
	{
		if(*plState)
			*plState=FALSE;
		else
			*plState=TRUE;
	}
	if(*plState)
	{
		HPEN hpen,holdpen;
		HBRUSH hbru,holdbru;
		hpen=CreatePen(PS_SOLID,0,RGB(128,128,255));
		hbru=CreateSolidBrush(RGB(210,210,255));
		holdpen=(HPEN)SelectObject(hdcMem,hpen);
		holdbru=(HBRUSH)SelectObject(hdcMem,hbru);
		RoundRect(hdcMem,0,0,rec.right,rec.bottom,8,8);
		SelectObject(hdcMem,holdpen);
		SelectObject(hdcMem,holdbru);
		DeleteObject(hpen);
		DeleteObject(hbru);
		SetBkColor(hdcMem,RGB(210,210,255));
	}
	else
	{
		HPEN hpen,holdpen;
		HBRUSH hbru,holdbru;
		hpen=CreatePen(PS_SOLID,0,RGB(50,50,50));
		hbru=CreateSolidBrush(RGB(90,90,90));
		holdpen=(HPEN)SelectObject(hdcMem,hpen);
		holdbru=(HBRUSH)SelectObject(hdcMem,hbru);
		RoundRect(hdcMem,0,0,rec.right,rec.bottom,8,8);
		SelectObject(hdcMem,holdpen);
		SelectObject(hdcMem,holdbru);
		DeleteObject(hpen);
		SetBkColor(hdcMem,RGB(90,90,90));
	}

	//get button text
	GetWindowText(lpdis->hwndItem,txt,50);
	DrawText(hdcMem,
		txt,lstrlen(txt),
		&rec,DT_VCENTER|DT_CENTER|DT_SINGLELINE);


	//update
	BitBlt(lpdis->hDC, 
               lpdis->rcItem.left,lpdis->rcItem.top, 
               lpdis->rcItem.right-lpdis->rcItem.left, lpdis->rcItem.bottom-lpdis->rcItem.top, 
               hdcMem, 
               0,0, 
               SRCCOPY);
	//release
	DeleteDC(hdcMem); 

}

#define OPEN_HCLK(index,offset) \
if(bnstate[index])\
	io_space->HCLKCON|=(1<<(offset));\
else\
	io_space->HCLKCON&=(~(1<<(offset)));

#define GET_HCLK(index,offset) \
if(io_space->HCLKCON&(1<<(offset)))\
	bnstate[index]=TRUE;\
else\
	bnstate[index]=FALSE;

static INT_PTR CALLBACK DialogProcClock(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	LPDRAWITEMSTRUCT lpdis; 
	HDC hdc;
	static HBITMAP memBM;
	static BOOL bnstate[15];
	static volatile S3C2443_CLKPWR_REG* io_space;

    switch (message)
    {
        case WM_INITDIALOG:	
            {
                // Create a Done button and size it.  
                SHINITDLGINFO shidi;
                shidi.dwMask = SHIDIM_FLAGS;
                shidi.dwFlags = SHIDIF_FULLSCREENNOMENUBAR;
                shidi.hDlg = hDlg;
                SHInitDialog(&shidi);
            }
			hdc=GetDC(hDlg);
			memBM = CreateCompatibleBitmap (hdc,100,100);
			ReleaseDC(hDlg,hdc);
			//
			io_space =(S3C2443_CLKPWR_REG*)VirtualAlloc( 0, sizeof(S3C2443_CLKPWR_REG), MEM_RESERVE, PAGE_NOACCESS );
			VirtualCopy( (LPVOID)io_space, (LPVOID)(0x4C000000 >> 8),sizeof(S3C2443_CLKPWR_REG), PAGE_PHYSICAL|PAGE_READWRITE|PAGE_NOCACHE );

			GET_HCLK(0,19);
			GET_HCLK(1,18);
			GET_HCLK(2,17);
			GET_HCLK(3,16);
			GET_HCLK(4,12);
			GET_HCLK(5,11);
			GET_HCLK(6,10);
			GET_HCLK(7,9);
			GET_HCLK(8,8);
			GET_HCLK(9,5);
			GET_HCLK(10,4);
			GET_HCLK(11,3);
			GET_HCLK(12,2);
			GET_HCLK(13,1);
			GET_HCLK(14,0);

            return (INT_PTR)TRUE;

		case WM_DRAWITEM: 
			lpdis = (LPDRAWITEMSTRUCT) lParam; 

			if((lpdis->CtlID>=IDB_DRAM)&&(lpdis->CtlID<=IDB_DMA5))
			{
				ClkBtnDraw(memBM,lpdis,bnstate+lpdis->CtlID-IDB_DRAM);
			}

			break;
        case WM_COMMAND:
			if(LOWORD(wParam)==IDOK)
			{
					//delete
					VirtualFree((LPVOID) io_space, 0, MEM_RELEASE );
					DeleteObject(memBM);
					EndDialog(hDlg, LOWORD(wParam));
			}
			else
			{
				if (HIWORD(wParam) == BN_CLICKED)
				{
					switch(LOWORD(wParam))
					{
					case IDB_DRAM:
						OPEN_HCLK(0,19);
						return TRUE;
					case IDB_SSMC:
						OPEN_HCLK(1,18);
						return TRUE;
					case IDB_CFC:
						OPEN_HCLK(2,17);
						return TRUE;
					case IDB_HSMMC:
						OPEN_HCLK(3,16);
						return TRUE;
					case IDB_USBDEV:OPEN_HCLK(4,12);return TRUE;
					case IDB_USBHOST:OPEN_HCLK(5,11);return TRUE;
					case IDB_STN:OPEN_HCLK(6,10);return TRUE;
					case IDB_TFT:OPEN_HCLK(7,9);return TRUE;
					case IDB_CAMIF:OPEN_HCLK(8,8);return TRUE;
					case IDB_DMA0:OPEN_HCLK(9,5);return TRUE;
					case IDB_DMA1:OPEN_HCLK(10,4);return TRUE;
					case IDB_DMA2:OPEN_HCLK(11,3);return TRUE;
					case IDB_DMA3:OPEN_HCLK(12,2);return TRUE;
					case IDB_DMA4:OPEN_HCLK(13,1);return TRUE;
					case IDB_DMA5:OPEN_HCLK(14,0);return TRUE;
					}
				}
			}
            break;

        case WM_CLOSE:
            EndDialog(hDlg, message);
            return TRUE;

    }
    return (INT_PTR)FALSE;
}
//-------------------------
#define OPEN_PCLK(index,offset) \
if(bnstate[index])\
	io_space->PCLKCON|=(1<<(offset));\
else\
	io_space->PCLKCON&=(~(1<<(offset)));

#define GET_PCLK(index,offset) \
if(io_space->PCLKCON&(1<<(offset)))\
	bnstate[index]=TRUE;\
else\
	bnstate[index]=FALSE;

static INT_PTR CALLBACK DialogProcPClock(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	LPDRAWITEMSTRUCT lpdis; 
	HDC hdc;
	static HBITMAP memBM;
	static BOOL bnstate[16];
	static volatile S3C2443_CLKPWR_REG* io_space;

    switch (message)
    {
        case WM_INITDIALOG:	
            {
                // Create a Done button and size it.  
                SHINITDLGINFO shidi;
                shidi.dwMask = SHIDIM_FLAGS;
                shidi.dwFlags = SHIDIF_FULLSCREENNOMENUBAR;
                shidi.hDlg = hDlg;
                SHInitDialog(&shidi);
            }
			hdc=GetDC(hDlg);
			memBM = CreateCompatibleBitmap (hdc,100,100);
			ReleaseDC(hDlg,hdc);
			//
			io_space =(S3C2443_CLKPWR_REG*)VirtualAlloc( 0, sizeof(S3C2443_CLKPWR_REG), MEM_RESERVE, PAGE_NOACCESS );
			VirtualCopy( (LPVOID)io_space, (LPVOID)(0x4C000000 >> 8),sizeof(S3C2443_CLKPWR_REG), PAGE_PHYSICAL|PAGE_READWRITE|PAGE_NOCACHE );

			GET_PCLK(0,0);
			GET_PCLK(1,1);
			GET_PCLK(2,2);
			GET_PCLK(3,3);
			GET_PCLK(4,4);
			GET_PCLK(5,5);
			GET_PCLK(6,6);
			GET_PCLK(7,7);
			GET_PCLK(8,8);
			GET_PCLK(9,9);
			GET_PCLK(10,10);
			GET_PCLK(11,11);
			GET_PCLK(12,12);
			GET_PCLK(13,13);
			GET_PCLK(14,14);
			GET_PCLK(15,15);

            return (INT_PTR)TRUE;

		case WM_DRAWITEM: 
			lpdis = (LPDRAWITEMSTRUCT) lParam; 

			if((lpdis->CtlID>=IDB_UART0)&&(lpdis->CtlID<=IDB_SPI1))
			{
				ClkBtnDraw(memBM,lpdis,bnstate+lpdis->CtlID-IDB_UART0);
			}

			break;
        case WM_COMMAND:
			if(LOWORD(wParam)==IDOK)
			{
					//delete
					VirtualFree((LPVOID) io_space, 0, MEM_RELEASE );
					DeleteObject(memBM);
					EndDialog(hDlg, LOWORD(wParam));
			}
			else
			{
				if (HIWORD(wParam) == BN_CLICKED)
				{
					switch(LOWORD(wParam))
					{
					case IDB_UART0:OPEN_PCLK(0,0);return TRUE;
					case IDB_UART1:OPEN_PCLK(1,1);return TRUE;
					case IDB_UART2:OPEN_PCLK(2,2);return TRUE;
					case IDB_UART3:OPEN_PCLK(3,3);return TRUE;
					case IDB_I2C:OPEN_PCLK(4,4);return TRUE;
					case IDB_SDMMC:OPEN_PCLK(5,5);return TRUE;
					case IDB_SPIHS:OPEN_PCLK(6,6);return TRUE;
					case IDB_TSADC:OPEN_PCLK(7,7);return TRUE;
					case IDB_AC97:OPEN_PCLK(8,8);return TRUE;
					case IDB_I2S:OPEN_PCLK(9,9);return TRUE;
					case IDB_PWM:OPEN_PCLK(10,10);return TRUE;
					case IDB_WDT:OPEN_PCLK(11,11);return TRUE;
					case IDB_RTC:OPEN_PCLK(12,12);return TRUE;
					case IDB_GPIO:OPEN_PCLK(13,13);return TRUE;
					case IDB_SPI0:OPEN_PCLK(14,14);return TRUE;
					case IDB_SPI1:OPEN_PCLK(15,15);return TRUE;
					}
				}
			}
            break;

        case WM_CLOSE:
            EndDialog(hDlg, message);
            return TRUE;

    }
    return (INT_PTR)FALSE;
}
//-------------------------
#define OPEN_SCLK(index,offset) \
if(bnstate[index])\
	io_space->SCLKCON|=(1<<(offset));\
else\
	io_space->SCLKCON&=(~(1<<(offset)));

#define GET_SCLK(index,offset) \
if(io_space->SCLKCON&(1<<(offset)))\
	bnstate[index]=TRUE;\
else\
	bnstate[index]=FALSE;

static INT_PTR CALLBACK DialogProcSClock(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	LPDRAWITEMSTRUCT lpdis; 
	HDC hdc;
	static HBITMAP memBM;
	static BOOL bnstate[10];
	static volatile S3C2443_CLKPWR_REG* io_space;

    switch (message)
    {
        case WM_INITDIALOG:	
            {
                // Create a Done button and size it.  
                SHINITDLGINFO shidi;
                shidi.dwMask = SHIDIM_FLAGS;
                shidi.dwFlags = SHIDIF_FULLSCREENNOMENUBAR;
                shidi.hDlg = hDlg;
                SHInitDialog(&shidi);
            }
			hdc=GetDC(hDlg);
			memBM = CreateCompatibleBitmap (hdc,200,70);
			ReleaseDC(hDlg,hdc);
			//
			io_space =(S3C2443_CLKPWR_REG*)VirtualAlloc( 0, sizeof(S3C2443_CLKPWR_REG), MEM_RESERVE, PAGE_NOACCESS );
			VirtualCopy( (LPVOID)io_space, (LPVOID)(0x4C000000 >> 8),sizeof(S3C2443_CLKPWR_REG), PAGE_PHYSICAL|PAGE_READWRITE|PAGE_NOCACHE );

			GET_SCLK(0,1);
			GET_SCLK(1,8);
			GET_SCLK(2,9);
			GET_SCLK(3,10);
			GET_SCLK(4,11);
			GET_SCLK(5,12);
			GET_SCLK(6,13);
			GET_SCLK(7,14);
			GET_SCLK(8,15);
			GET_SCLK(9,16);

            return (INT_PTR)TRUE;

		case WM_DRAWITEM: 
			lpdis = (LPDRAWITEMSTRUCT) lParam; 

			if((lpdis->CtlID>=IDB_USBHOSTE)&&(lpdis->CtlID<=IDB_DDR))
			{
				ClkBtnDraw(memBM,lpdis,bnstate+lpdis->CtlID-IDB_USBHOSTE);
			}

			break;
        case WM_COMMAND:
			if(LOWORD(wParam)==IDOK)
			{
					//delete
					VirtualFree((LPVOID) io_space, 0, MEM_RELEASE );
					DeleteObject(memBM);
					EndDialog(hDlg, LOWORD(wParam));
			}
			else
			{
				if (HIWORD(wParam) == BN_CLICKED)
				{
					switch(LOWORD(wParam))
					{
					case IDB_USBHOSTE:OPEN_SCLK(0,1);return TRUE;
					case IDB_UARTCLK:OPEN_SCLK(1,8);return TRUE;
					case IDB_I2SCLK:OPEN_SCLK(2,9);return TRUE;
					case IDB_DISPCLK:OPEN_SCLK(3,10);return TRUE;
					case IDB_CAMIFE:OPEN_SCLK(4,11);return TRUE;
					case IDB_HSMMC_EPLL:OPEN_SCLK(5,12);return TRUE;
					case IDB_HSMMC_EXT:OPEN_SCLK(6,13);return TRUE;
					case IDB_HSSPI:OPEN_SCLK(7,14);return TRUE;
					case IDB_SSMCE:OPEN_SCLK(8,15);return TRUE;
					case IDB_DDR:OPEN_SCLK(9,16);return TRUE;
					}
				}
			}
            break;

        case WM_CLOSE:
            EndDialog(hDlg, message);
            return TRUE;

    }
    return (INT_PTR)FALSE;
}
//------------------------------------------------------------------------
static inline const TCHAR * PageState(PMEMORY_BASIC_INFORMATION pinfo)
{
	switch(pinfo->State)
	{
	case MEM_FREE:
		return _T("F");
	case MEM_COMMIT:
		return _T("C");
	case MEM_RESERVE:
		return _T("R");
	}
	return _T(" ");
}
static inline const TCHAR * PageType(PMEMORY_BASIC_INFORMATION pinfo)
{
	switch(pinfo->Type)
	{
	case MEM_IMAGE:
		return _T("Image");
	case MEM_MAPPED:
		return _T("Mapped");
	case MEM_PRIVATE:
		return _T("Priv");
	}
	return _T(" ");
}

static INT_PTR CALLBACK DialogProcSYS(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	HDC hdc;
	RECT rec;
	PAINTSTRUCT ps; 
	SYSTEM_INFO sysinfo;
	OSVERSIONINFO verinfo;
	MEMORYSTATUS meminfo;
	static TCHAR txt[256];
	DWORD sysintr=0,dwret;
	TCHAR * tleft,*tright;
	int len;
	static CAppleList * Alist; 
	static HBRUSH hbgbrush;

    switch (message)
    {
        case WM_INITDIALOG:	
            {
                // Create a Done button and size it.  
                SHINITDLGINFO shidi;
                shidi.dwMask = SHIDIM_FLAGS;
                shidi.dwFlags = SHIDIF_FULLSCREENNOMENUBAR;
                shidi.hDlg = hDlg;
                SHInitDialog(&shidi);
            }

			//get system info
			GetSystemInfo(&sysinfo);
			GetVersionEx(&verinfo);
			GlobalMemoryStatus(&meminfo);

			//
			if ( !KernelIoControl(IOCTL_HAL_GET_WAKE_SOURCE, NULL, 0, &sysintr, sizeof(sysintr),&dwret))	  	
			{
				//ERRORMSG(ZONE_ERROR, (TEXT("Read IOCTL_MIO_PreShutdown fail.\r\n")));
			} 
			else
			{
				//RETAILMSG(ZONE_INFO, (TEXT("Read IOCTL_MIO_PreShutdown success.\r\n")));
			}	
			//
			GetClientRect(hDlg,&rec);
			InflateRect(&rec,-8,-20);
			hdc=GetDC(hDlg);
			Alist=new CAppleList(hdc,&rec);
			ReleaseDC(hDlg,hdc);
			hbgbrush=CreateSolidBrush(RGB(180,180,255));
			//formatting text
			tleft=txt;
			len=wsprintf(tleft,_T("Page size"));
			tright=tleft+len+1;
			len=wsprintf(tright,_T("0x%x"),sysinfo.dwPageSize);
			Alist->Add(tleft,tright);
			tleft=tright+len+1;
			//
			len=wsprintf(tleft,_T("User Start"));
			tright=tleft+len+1;
			len=wsprintf(tright,_T("0x%08X"),sysinfo.lpMinimumApplicationAddress);
			Alist->Add(tleft,tright);
			tleft=tright+len+1;
			//
			len=wsprintf(tleft,_T("User End"));
			tright=tleft+len+1;
			len=wsprintf(tright,_T("0x%08X"),sysinfo.lpMaximumApplicationAddress);
			Alist->Add(tleft,tright);
			tleft=tright+len+1;
			//
			len=wsprintf(tleft,_T("CPU number"));
			tright=tleft+len+1;
			len=wsprintf(tright,_T("%d"),sysinfo.dwNumberOfProcessors);
			Alist->Add(tleft,tright);
			tleft=tright+len+1;
			//
			len=wsprintf(tleft,_T("Alloc G"));
			tright=tleft+len+1;
			len=wsprintf(tright,_T("0x%x"),sysinfo.dwAllocationGranularity);
			Alist->Add(tleft,tright);
			tleft=tright+len+1;
			//
			len=wsprintf(tleft,_T("WakeUp SysIntr"));
			tright=tleft+len+1;
			len=wsprintf(tright,_T("0x%x"),sysintr);
			Alist->Add(tleft,tright);
			tleft=tright+len+1;

            return (INT_PTR)TRUE;
		case WM_ERASEBKGND:
			hdc = (HDC) wParam;
			SelectObject(hdc,hbgbrush);
			GetClientRect(hDlg,&rec);
			FillRect(hdc,&rec,hbgbrush);
			return TRUE;
		case WM_PAINT:
			hdc = BeginPaint(hDlg, &ps); 
			Alist->Paint(hdc);
			EndPaint(hDlg, &ps); 
			return 0;
        case WM_COMMAND:
            switch(LOWORD(wParam))
            {
			case IDOK:
				//delete
				EndDialog(hDlg, LOWORD(wParam));
				break;
            }
            break;

        case WM_DESTROY:
			delete Alist;
			DeleteObject(hbgbrush);
            EndDialog(hDlg, message);
            return TRUE;

    }
    return (INT_PTR)FALSE;
}

typedef struct _HUNGUP_DEBUG
{
	DWORD	wkupSRCPNDbkup;	//store wake up SRCPND register content
	DWORD   wkupWKUPSTATbkup;	//store wake up WKUPSTAT register content
	DWORD   procedure1;
	DWORD   wkupRSTSTATbkup;	//store wake up RSTSTAT register content
}HUNGUP_DEBUG,* PHUNGUP_DEBUG;

#define IOCTL_HAL_WAKEUP_STATUS	CTL_CODE(FILE_DEVICE_HAL, 5080, METHOD_BUFFERED, FILE_ANY_ACCESS)

typedef BOOL (*GETADDRFN)();
static INT_PTR CALLBACK DialogProcLB(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	HDC hdc;
	RECT rec;
	PAINTSTRUCT ps; 
	static TCHAR txt[256];
	DWORD sysintr=0,dwret;
	TCHAR * tleft,*tright;
	int len;
	static CAppleList * Alist; 
	static HBRUSH hbgbrush;
	HUNGUP_DEBUG hang;
	static HINSTANCE hCoreDll;
	static GETADDRFN pfnGetAddr=NULL;


    switch (message)
    {
        case WM_INITDIALOG:	
            {
                // Create a Done button and size it.  
                SHINITDLGINFO shidi;
                shidi.dwMask = SHIDIM_FLAGS;
                shidi.dwFlags = SHIDIF_FULLSCREENNOMENUBAR;
                shidi.hDlg = hDlg;
                SHInitDialog(&shidi);
            }
			
			//
			if ( !KernelIoControl(IOCTL_HAL_WAKEUP_STATUS, &hang, sizeof(hang),NULL,0,&dwret))	  	
			{
				//ERRORMSG(ZONE_ERROR, (TEXT("Read IOCTL_MIO_PreShutdown fail.\r\n")));
			} 
			else
			{
				//RETAILMSG(ZONE_INFO, (TEXT("Read IOCTL_MIO_PreShutdown success.\r\n")));
			}	
			//
			GetClientRect(hDlg,&rec);
			InflateRect(&rec,-8,-20);
			hdc=GetDC(hDlg);
			Alist=new CAppleList(hdc,&rec);
			ReleaseDC(hDlg,hdc);
			hbgbrush=CreateSolidBrush(RGB(180,180,255));
			//formatting text
			tleft=txt;
			len=wsprintf(tleft,_T("WKUPSTAT"));
			tright=tleft+len+1;
			len=wsprintf(tright,_T("0x%x"),hang.wkupWKUPSTATbkup);
			Alist->Add(tleft,tright);
			tleft=tright+len+1;
			//
			len=wsprintf(tleft,_T("SRCPND"));
			tright=tleft+len+1;
			len=wsprintf(tright,_T("0x%08X"),hang.wkupSRCPNDbkup);
			Alist->Add(tleft,tright);
			tleft=tright+len+1;
			//
			len=wsprintf(tleft,_T("RSTSTAT"));
			tright=tleft+len+1;
			len=wsprintf(tright,_T("0x%08X"),hang.wkupRSTSTATbkup);
			Alist->Add(tleft,tright);
			tleft=tright+len+1;
			//
			len=wsprintf(tleft,_T("PROC"));
			tright=tleft+len+1;
			len=wsprintf(tright,_T("0x%08X"),hang.procedure1);
			Alist->Add(tleft,tright);
			tleft=tright+len+1;

			//
			hCoreDll = LoadLibrary(TEXT("ceddk.dll"));
			if(hCoreDll)
			{
				pfnGetAddr = (GETADDRFN)GetProcAddress(hCoreDll, TEXT("IsBluetoothOnly"));
				if(!pfnGetAddr)
				{
					MessageBox(hDlg,_T("cannot find IsBluetoothOnly()"),_T("error"),MB_ICONEXCLAMATION|MB_TOPMOST);
				}
			}
			else
				MessageBox(hDlg,_T("load ceddk.dll error"),_T("error"),MB_ICONEXCLAMATION|MB_TOPMOST);
			//
			if(pfnGetAddr)
			{
			len=wsprintf(tleft,_T("Function"));
			tright=tleft+len+1;
			len=wsprintf(tright,_T("%s"),(pfnGetAddr()?_T("BT"):_T("BT WIFI")));
			Alist->Add(tleft,tright);
			tleft=tright+len+1;				
			}
            return (INT_PTR)TRUE;
		case WM_ERASEBKGND:
			hdc = (HDC) wParam;
			SelectObject(hdc,hbgbrush);
			GetClientRect(hDlg,&rec);
			FillRect(hdc,&rec,hbgbrush);
			return TRUE;
		case WM_PAINT:
			hdc = BeginPaint(hDlg, &ps); 
			Alist->Paint(hdc);
			EndPaint(hDlg, &ps); 
			return 0;
        case WM_COMMAND:
            switch(LOWORD(wParam))
            {
			case IDOK:
				//delete
				EndDialog(hDlg, LOWORD(wParam));
				break;
            }
            break;

        case WM_DESTROY:
			delete Alist;
			DeleteObject(hbgbrush);
            EndDialog(hDlg, message);
			if (hCoreDll)
			{
				FreeLibrary(hCoreDll);
			}
            return TRUE;

    }
    return (INT_PTR)FALSE;
}
//------------------------------------------------------------------------
static INT_PTR CALLBACK DialogProcCPU(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	HDC hdc;
	static RECT rec;
	PAINTSTRUCT ps; 
	TCHAR txt[256];
	int len;
	static HBRUSH hbgbrush;
	static LONGLONG PercentIdle;
	static HPEN hpen;
	HPEN holdpen;
	static CPUMeasure * cpupercent;

    switch (message)
    {
        case WM_INITDIALOG:	
            {
                // Create a Done button and size it.  
                SHINITDLGINFO shidi;
                shidi.dwMask = SHIDIM_FLAGS;
                shidi.dwFlags = SHIDIF_FULLSCREENNOMENUBAR;
                shidi.hDlg = hDlg;
                SHInitDialog(&shidi);
            }
			//init GDI
			GetClientRect(hDlg,&rec);

			hbgbrush=CreateSolidBrush(RGB(0,0,0));
			hpen=CreatePen(PS_SOLID,0,RGB(0,255,0));
			cpupercent=new CPUMeasure();
			//timer start
			SetTimer(hDlg,1105,2000,NULL);
            return (INT_PTR)TRUE;
		case WM_ERASEBKGND:
			hdc = (HDC) wParam;
			SelectObject(hdc,hbgbrush);
			GetClientRect(hDlg,&rec);
			FillRect(hdc,&rec,hbgbrush);
			return TRUE;
		case WM_PAINT:
			GetClientRect(hDlg,&rec);
			hdc = BeginPaint(hDlg, &ps); 
			SetBkMode(hdc,TRANSPARENT);
			holdpen=(HPEN)SelectObject(hdc,hpen);
			len=wsprintf(txt,_T("%d %%"),cpupercent->chCPUHistory);
			SetTextColor(hdc,RGB(0,255,0));
			DrawText(hdc,txt, len,&rec,DT_CENTER|DT_VCENTER); 
			EndPaint(hDlg, &ps); 
			return 0;
		case WM_TIMER:
			cpupercent->Measure();
			RedrawWindow(hDlg,NULL,NULL,RDW_INVALIDATE|RDW_ERASE);
			return 0;
        case WM_COMMAND:
            switch(LOWORD(wParam))
            {
			case IDOK:
				//delete
				EndDialog(hDlg, LOWORD(wParam));
				break;
            }
            break;

        case WM_DESTROY:
			delete cpupercent;
			DeleteObject(hbgbrush);
            EndDialog(hDlg, message);
            return TRUE;

    }
    return (INT_PTR)FALSE;
}
//----------------------------------------------------------------------------
static INT_PTR CALLBACK DialogProcGDI(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	HDC hdc;
	RECT rec;
	PAINTSTRUCT ps; 
	static struct CapData
	{
		int Ver;
		int ColorBits;
		int ColorRes;
		int Raster;
		BOOL bPalete;
		int Npal;
		//
		int HorzPix;
		int HorzMM;
		int Xpixinch;
		//
		int VertPix;
		int VertMM;
		int Ypixinch;
		//
		int Nbrush;
		int Nfont;
		int Npen;
	}capdata;
	static TCHAR txtname[256];
	TCHAR * tleft,*tright;
	int len;
	static CAppleList * Alist;
	static HBRUSH hbgbrush;

    switch (message)
    {
        case WM_INITDIALOG:	
			//SHEnableSoftkey(g_hWndMenuBar, /*uid*, 0 for SK1, 1 for SK2*/1, /*bByIndex*/TRUE, FALSE);
            {
                // Create a Done button and size it.  
                SHINITDLGINFO shidi;
                shidi.dwMask = SHIDIM_FLAGS;
                //shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN | SHIDIF_SIZEDLGFULLSCREEN | SHIDIF_EMPTYMENU;
				shidi.dwFlags=SHIDIF_FULLSCREENNOMENUBAR;
                shidi.hDlg = hDlg;
                SHInitDialog(&shidi);
            }


			hdc=GetDC(hDlg);
			//
			capdata.Ver=GetDeviceCaps(hdc,DRIVERVERSION);
			capdata.Raster=GetDeviceCaps(hdc,RASTERCAPS);
			capdata.ColorBits= GetDeviceCaps(hdc,BITSPIXEL);
			//wide info
			capdata.HorzPix= GetDeviceCaps(hdc,HORZRES);
			capdata.HorzMM= GetDeviceCaps(hdc,HORZSIZE);
			// pixels per inch in wide
			capdata.Xpixinch= GetDeviceCaps(hdc,LOGPIXELSX);
			//high info
			capdata.VertPix= GetDeviceCaps(hdc,VERTRES);
			capdata.VertMM= GetDeviceCaps(hdc,VERTSIZE);
			// pixels per inch in hight
			capdata.Ypixinch= GetDeviceCaps(hdc,LOGPIXELSY);
			//GDI object
			capdata.Nbrush= GetDeviceCaps(hdc,NUMBRUSHES);
			capdata.Nfont= GetDeviceCaps(hdc,NUMFONTS);
			capdata.Npen= GetDeviceCaps(hdc,NUMPENS);
			if( RC_PALETTE & capdata.Raster )
			{
				capdata.bPalete=TRUE;
				// have palete
				capdata.ColorRes=GetDeviceCaps(hdc,COLORRES);
				capdata.Npal=GetDeviceCaps(hdc,SIZEPALETTE);
			}
			else
			{
				capdata.bPalete=FALSE;
			}
			//
			GetClientRect(hDlg,&rec);
			InflateRect(&rec,-8,-20);
			Alist=new CAppleList(hdc,&rec);
			hbgbrush=CreateSolidBrush(RGB(180,180,255));
			//formatting text
			tleft=txtname;
			len=wsprintf(tleft,_T("GDI Version"));
			tright=tleft+len+1;
			len=wsprintf(tright,_T("0x%08x"),capdata.Ver);
			Alist->Add(tleft,tright);
			tleft=tright+len+1;
			//
			len=wsprintf(tleft,_T("Resolution"));
			tright=tleft+len+1;
			len=wsprintf(tright,_T("%dx%d"),capdata.HorzPix,capdata.VertPix);
			Alist->Add(tleft,tright);
			tleft=tright+len+1;
			//
			len=wsprintf(tleft,_T("Screen"));
			tright=tleft+len+1;
			len=wsprintf(tright,_T("%dx%d"),capdata.HorzMM,capdata.VertMM);
			Alist->Add(tleft,tright);
			tleft=tright+len+1;
			//
			len=wsprintf(tleft,_T("Color width"));
			tright=tleft+len+1;
			len=wsprintf(tright,_T("%d"),capdata.ColorBits);
			Alist->Add(tleft,tright);
			tleft=tright+len+1;
			//
			len=wsprintf(tleft,_T("Palette"));
			tright=tleft+len+1;
			len=wsprintf(tright,_T("%s"),(capdata.bPalete?_T("yes"):_T("no")));
			Alist->Add(tleft,tright);
			tleft=tright+len+1;
		
			ReleaseDC(hDlg,hdc);
            return (INT_PTR)TRUE;
		case WM_ERASEBKGND:
			hdc = (HDC) wParam;
			SelectObject(hdc,hbgbrush);
			GetClientRect(hDlg,&rec);
			FillRect(hdc,&rec,hbgbrush);
			return TRUE;
		case WM_PAINT:
			hdc = BeginPaint(hDlg, &ps); 
			Alist->Paint(hdc);
			EndPaint(hDlg, &ps); 
			return 0;
        case WM_COMMAND:
            switch(LOWORD(wParam))
            {
			case IDOK:
				//delete
				EndDialog(hDlg, LOWORD(wParam));
				break;
            }
            break;

        case WM_DESTROY:
			delete Alist;
			DeleteObject(hbgbrush);
            EndDialog(hDlg, message);
            return TRUE;

    }
    return (INT_PTR)FALSE;
}
// ------------------------ DEVICE ID MANAGEMENT ------------------------

static BOOL
HexStringToDword(LPCWSTR FAR& lpsz, DWORD FAR& Value,
                 int cDigits, WCHAR chDelim)
{
	int Count;

	Value = 0;
	for (Count = 0; Count < cDigits; Count++, lpsz++)
	{
		if (*lpsz >= '0' && *lpsz <= '9')
			Value = (Value << 4) + *lpsz - '0';
		else if (*lpsz >= 'A' && *lpsz <= 'F')
			Value = (Value << 4) + *lpsz - 'A' + 10;
		else if (*lpsz >= 'a' && *lpsz <= 'f')
			Value = (Value << 4) + *lpsz - 'a' + 10;
		else
			return(FALSE);
	}

	if (chDelim != 0)
		return *lpsz++ == chDelim;
	else
		return TRUE;
}


static BOOL
wUUIDFromString(LPCWSTR lpsz, LPGUID pguid)
{
	DWORD dw;

	if (!HexStringToDword(lpsz, pguid->Data1, sizeof(DWORD)*2, '-'))
		return FALSE;

	if (!HexStringToDword(lpsz, dw, sizeof(WORD)*2, '-'))
		return FALSE;

	pguid->Data2 = (WORD)dw;

	if (!HexStringToDword(lpsz, dw, sizeof(WORD)*2, '-'))
		return FALSE;

	pguid->Data3 = (WORD)dw;

	if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
		return FALSE;

	pguid->Data4[0] = (BYTE)dw;

	if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, '-'))
		return FALSE;

	pguid->Data4[1] = (BYTE)dw;

	if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
		return FALSE;

	pguid->Data4[2] = (BYTE)dw;

	if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
		return FALSE;

	pguid->Data4[3] = (BYTE)dw;

	if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
		return FALSE;

	pguid->Data4[4] = (BYTE)dw;

	if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
		return FALSE;

	pguid->Data4[5] = (BYTE)dw;

	if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
		return FALSE;

	pguid->Data4[6] = (BYTE)dw;
	if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
		return FALSE;

	pguid->Data4[7] = (BYTE)dw;

	return TRUE;
}

static BOOL
GUIDFromString(LPCWSTR lpsz, LPGUID pguid)
{
	if (*lpsz++ != '{' )
		return FALSE;

	if(wUUIDFromString(lpsz, pguid) != TRUE)
		return FALSE;

	lpsz +=36;

	if (*lpsz++ != '}' )
		return FALSE;

	return TRUE;
}

// this routine converts a text string to a GUID if possible.
BOOL
ConvertStringToGuid (LPCTSTR pszGuid, GUID *pGuid)
{
	BOOL fOk = FALSE;
	TCHAR txt[512];

	DEBUGCHK(pGuid != NULL && pszGuid != NULL);

	if (! GUIDFromString(pszGuid, pGuid))
	{
		wsprintf(txt,_T("couldn't parse '%s'\r\n"),pszGuid);
		MessageBox(0, txt,_T("error"),MB_ICONEXCLAMATION|MB_TOPMOST);
	}
	fOk = TRUE;

	return fOk;
}
//------------------------------------------------------------------------------------------------------
DWORD EnumDevice(HTREEITEM father,GUID * pguid)
{
	TCHAR txt[512];
	HANDLE hsearch;
	DEVMGR_DEVICE_INFORMATION  devinfo;

	memset(&devinfo,0,sizeof(devinfo));
	devinfo.dwSize=sizeof(devinfo);

	hsearch=FindFirstDevice(DeviceSearchByGuid,pguid,&devinfo);
	if(hsearch==INVALID_HANDLE_VALUE)
	{

		wsprintf(txt,_T("Finddevice Failed: %d"),GetLastError());
		//MessageBox(0, txt,_T("error"),MB_ICONEXCLAMATION|MB_TOPMOST);
		return 0;
	}

	do
	{
		CEDevice * pdev;
		pdev=(CEDevice *)malloc(sizeof(CEDevice));
		if(!pdev)
			return FALSE;
		memset(pdev,0,sizeof(CEDevice));
		memcpy(&pdev->info,&devinfo,sizeof(devinfo));
		pdev->popt=&g_StreamOpt;
		wsprintf(txt,_T("%s"),devinfo.szLegacyName);
		TabPageInit(TP_StreamDev,dim(TP_StreamDev));
		pdev->pTPheader=TP_StreamDev;
		pdev->type=CEDT_STREAM;
		//MessageBox(0, txt,_T("dev info"),MB_OK|MB_TOPMOST);
		HTREEITEM hdev=p_pmlv->AddChild(father,pdev,txt,sizeof(txt));	
	}
	while(FindNextDevice(hsearch,&devinfo));

	FindClose(hsearch);
	return TRUE;
}
DWORD EnumDisplay(HTREEITEM father,GUID * pguid)
{
	struct dev_opt * opt=&g_DisplayOpt;
	HANDLE hdevice;
	TCHAR txt[512];
	CEDevice * pdev;

	hdevice=opt->Open(_T(""));
	if(hdevice==INVALID_HANDLE_VALUE)
	{
		return FALSE;
	}
	opt->Close(hdevice);
		
	pdev=(CEDevice *)malloc(sizeof(CEDevice));
	if(!pdev)
		return FALSE;
	memset(pdev,0,sizeof(CEDevice));

	pdev->popt=&g_DisplayOpt;
	wsprintf(txt,_T("Display"));
	TabPageInit(TP_DisplayDev,dim(TP_DisplayDev));
	pdev->pTPheader=TP_DisplayDev;
	pdev->type=CEDT_DISPLAY;
	//MessageBox(0, txt,_T("dev info"),MB_OK|MB_TOPMOST);
	HTREEITEM hdev=p_pmlv->AddChild(father,pdev,txt,sizeof(txt));	
	return TRUE;
}


DWORD EnumInterfaces()
{
	TCHAR txt[512],txtval[512];
	DWORD dwStatus;
	HKEY hk;
	
	wsprintf(txt, _T("%s\\Interfaces"), _T("SYSTEM\\CurrentControlSet\\Control\\Power"));
	dwStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, txt, 0, 0, &hk);
	if(dwStatus == ERROR_SUCCESS) 
	{
		DWORD dwIndex = 0;
		do 
		{
			DWORD cbValueName = dim(txt), dwType;
			GUID idInterface;
			DWORD cbval=sizeof(txtval);

			dwStatus = RegEnumValue(hk, dwIndex, txt, &cbValueName, NULL,&dwType, (LPBYTE)txtval, &cbval);
			if(dwStatus == ERROR_SUCCESS) 
			{
				if(dwType != REG_SZ) 
				{
					wsprintf(txt,_T("invalid type for value '%s'\r\n"),txt);
					MessageBox(0, txt,_T("error"),MB_ICONEXCLAMATION|MB_TOPMOST);
				} 
				else if(!ConvertStringToGuid(txt, &idInterface)) 
				{
					wsprintf(txt,_T("can't convert '%s' to GUID\r\n"),txt);
					MessageBox(0, txt,_T("error"),MB_ICONEXCLAMATION|MB_TOPMOST);						
				}
				else
				{
					//HTREEITEM hinter=p_pmlv->AddChild(NULL,txtval,sizeof(txtval));

					CEDevice * pdev;
					pdev=(CEDevice *)malloc(sizeof(CEDevice));
					if(!pdev)
						return FALSE;
					memset(pdev,0,sizeof(CEDevice));
					memcpy(&pdev->guid,&idInterface,sizeof(idInterface));

					TabPageInit(TP_Interface,dim(TP_Interface));
					pdev->pTPheader=TP_Interface;
					pdev->type=CEDT_INTERFACE;
					HTREEITEM hinter=p_pmlv->AddChild(NULL,pdev,txtval,sizeof(txtval));	

					if(idInterface == idPMDisplayDeviceClass)
						EnumDisplay(hinter,&idInterface);
					else
						EnumDevice(hinter,&idInterface);
				}
			}
			dwIndex++;
		}while(dwStatus == ERROR_SUCCESS);
		RegCloseKey(hk);
	} 	
	
	return true;
}



void PMTabCtrl::RefreshPage()
{
	int item;
	item=TabCtrl_GetCurSel(g_hwnd);
	TabCtrl_SetCurSel(g_hwnd,-1);
	TabCtrl_SetCurFocus(g_hwnd,item);
}
void PMTabCtrl::SelectChange()
{
	int sel,i=0;
	CEDevice * pdev=g_pCurDevice;
	TabPage * ptp;

	
	sel=TabCtrl_GetCurSel(g_hwnd);
	if(pdlg)
		delete pdlg;
	pdlg=NULL;

	if(!pdev)
		return;
	if(!(pdev->pTPheader))
		return;

	ptp=pdev->pTPheader;

	while(ptp)
	{
		if(sel==i)
		{
			pdlg=new PMDialog(g_hwnd,ptp->lpResource,ptp->DialogProc);
			break;
		}
		ptp=ptp->next;
		i++;
	}

}
DWORD PMTabCtrl::Notify(int idCtrl,LPNMHDR pnmh)
{	
	switch(pnmh->code)
	{
		case TCN_SELCHANGE:
			SelectChange();
			break;
	}
	return TRUE;
}
DWORD PMTabCtrl::ReSize()
{
	RECT rect;
	GetClientRect(g_hpwnd,&rect);
	//SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, FALSE);	
	MoveWindow(g_hwnd,rect.left,p_pmsplit->WndRect.bottom,rect.right-rect.left,(rect.bottom-p_pmsplit->WndRect.bottom),true);
	if(pdlg)
		PMDialog::ReSize(pdlg->g_hwnd);
	return true;
}

int PMTabCtrl::AddPage(int id,TabPage * ptp,LPTSTR txt,int len)
{
	TCITEM item;
	memset(&item,0,sizeof(item));
	item.mask=TCIF_TEXT|TCIF_RTLREADING|TCIF_STATE|TCIF_IMAGE|TCIF_PARAM;
	item.pszText=txt;
	item.cchTextMax=len;
	item.iImage=6;
	item.lParam=(LPARAM)ptp;
	//item.state=TVIS_EXPANDED;
	//item.stateMask=TVIS_EXPANDED;

	return TabCtrl_InsertItem(g_hwnd,id,&item);
}
void PMTabCtrl::ChangeView()
{
	int i=0;
	CEDevice * pdev=g_pCurDevice;
	TabPage *ptp;

	if(pdlg)
		delete pdlg;
	pdlg=NULL;

	TabCtrl_DeleteAllItems(g_hwnd);
	ptp=g_pCurDevice->pTPheader;
	while(ptp)
	{
		AddPage(i,ptp,ptp->lpcaption,ptp->len);
		i++;
		ptp=ptp->next;
	}
}

void  PMTabCtrl::SetPage(int id,BOOL ok)
{
	TCITEM item;
	TCHAR txt[512];
	
	memset(&item,0,sizeof(item));

	item.pszText=txt;
	item.cchTextMax=sizeof(txt);
	TabCtrl_GetItem(g_hwnd,id,&item);
	if(ok)
		item.iImage=4;
	else
		item.iImage=3;
	TabCtrl_SetItem(g_hwnd,id,&item);

}

PMTabCtrl::PMTabCtrl(HWND hWnd):PMControl()
{
	RECT rect;

	//no dialog open;
	pdlg=NULL;
	
	GetClientRect(hWnd,&rect);
	g_hwnd = CreateWindowEx (  0,  WC_TABCONTROL, TEXT("Device Tab"),
		WS_VISIBLE | WS_CHILD | WS_BORDER,
		0,rect.bottom/2+rect.top,rect.right,rect.bottom, hWnd,(HMENU)NULL,g_hInst, NULL);

	Update();

	TabCtrl_SetImageList(g_hwnd,g_ImgList);
	//AddPage(0,_T("Power"),20);
	//AddPage(1,_T("Info"),20);
	//AddPage(2,_T("Module"),20);
	SelectChange();
}


PMTaskBar::PMTaskBar()
{
	DWORD cx,cy;
	g_hwnd = FindWindow(_T("HHTaskBar"), NULL);
	GetWindowRect(g_hwnd,&rect);
	//ShowWindow(hWndTaskbar, SW_HIDE);
	cx=GetSystemMetrics(SM_CXSCREEN);
	cy=GetSystemMetrics(SM_CYSCREEN);
	MoveWindow(g_hwnd, rect.left,cy-rect.bottom-rect.top,cx ,rect.bottom-rect.top, FALSE);
}
PMTaskBar::~PMTaskBar()
{
	DWORD cx,cy;
	cx=GetSystemMetrics(SM_CXSCREEN);
	cy=GetSystemMetrics(SM_CYSCREEN);
	MoveWindow(g_hwnd, 0,rect.top,cx ,rect.bottom-rect.top, FALSE);
}

PMModule::PMModule(TCHAR * DevName,TCHAR * ModuleName)
{
	//init
    fnInit=NULL;
    fnPreDeinit=NULL;
    fnDeinit=NULL;
    fnOpen=NULL;
    fnPreClose=NULL;
    fnClose=NULL;
    fnRead=NULL;
    fnWrite=NULL;
    fnSeek=NULL;
    fnControl=NULL;
    fnPowerup=NULL;
    fnPowerdn=NULL;
	//handle of module
	hmodule=NULL;

	hmodule=LoadLibrary(ModuleName);
	if(hmodule)
	{
		fnInit=(pInitFn)GetDMProcAddr(DevName,_T("Init"));
		fnPreDeinit=(pDeinitFn)GetDMProcAddr(DevName,_T("PreDeinit"));
		fnDeinit=(pDeinitFn)GetDMProcAddr(DevName,_T("Deinit"));
		fnOpen=(pOpenFn)GetDMProcAddr(DevName,_T("Open"));
		fnPreClose=(pCloseFn)GetDMProcAddr(DevName,_T("PreClose"));
		fnClose=(pCloseFn)GetDMProcAddr(DevName,_T("Close"));
		fnRead=(pReadFn)GetDMProcAddr(DevName,_T("Read"));
		fnWrite=(pWriteFn)GetDMProcAddr(DevName,_T("Write"));
		fnSeek=(pSeekFn)GetDMProcAddr(DevName,_T("Seek"));
		fnControl=(pControlFn)GetDMProcAddr(DevName,_T("IOControl"));
		fnPowerup=(pPowerupFn)GetDMProcAddr(DevName,_T("PowerUp"));
		fnPowerdn=(pPowerupFn)GetDMProcAddr(DevName,_T("PowerDown"));
	}
}
PMModule::~PMModule()
{
	if(hmodule)
		FreeLibrary(hmodule);
}

BOOL PMModule::GetModuleInfo(LPMODULEINFO lpmodinfo)
{
	return GetModuleInformation(GetCurrentProcess(),hmodule,lpmodinfo,sizeof(MODULEINFO));
}

LPVOID PMModule::GetDMProcAddr(TCHAR * DevName,TCHAR * FuncName)
{
	TCHAR fullname[32];
	TCHAR * s;

    if (DevName != NULL && *DevName != _T('\0')) 
	{
        memcpy(fullname,DevName,3*sizeof(TCHAR));
        fullname[3] = _T('_');
        _tcscpy(&fullname[4],FuncName);
        s = fullname;
    }
	else 
	{
        s = FuncName;
    }
	//MessageBox(0,fullname,_T("mod"),MB_OK|MB_TOPMOST);
    return (LPVOID)GetProcAddress(hmodule, s);
}
//------------------------------------------------
static HWND CreateBar(HWND hWnd)
{	
		static REBARBANDINFO rbi[2];
		HWND hbar;
		
		memset(rbi, 0, sizeof (rbi));
		// REBARBANDINFO for the menu band.
		rbi[0].cbSize = sizeof (REBARBANDINFO);
		rbi[0].fMask = RBBIM_STYLE | RBBIM_ID | RBBIM_SIZE;
		rbi[0].fStyle = RBBS_CHILDEDGE | RBBS_NOGRIPPER;
		rbi[0].wID = ID_BAND_MENUBAR;
		rbi[0].cx = 10;
  
		// REBARBANDINFO for the main toolbar band.
		rbi[1].cbSize = sizeof (REBARBANDINFO);
		rbi[1].fMask = RBBIM_TEXT | RBBIM_ID | RBBIM_IMAGE | RBBIM_STYLE| RBBIM_SIZE;
		rbi[1].fStyle = RBBS_GRIPPERALWAYS;
		rbi[1].lpText = TEXT("Toolbar");
		rbi[1].wID = ID_BAND_TOOLBAR;
		rbi[1].cx = 50;
		rbi[1].iImage = 4;
		rbi[1].cxMinChild=10;
		rbi[1].cxIdeal=10;
	
		//
		g_hwndCB =CommandBands_Create (g_hInst, hWnd, IDC_CMDBAR1 ,
		        RBS_VARHEIGHT | RBS_BANDBORDERS | RBS_AUTOSIZE, NULL);

		CommandBands_AddBands (g_hwndCB, g_hInst, 2, rbi);
		if(hbar=CommandBands_GetCommandBar (g_hwndCB, 0))
			CommandBar_InsertMenubar (hbar, g_hInst, IDR_MENU, 0);
		
		//if(hbar=CommandBands_GetCommandBar (g_hwndCB, 1))
		//	CommandBar_AddBitmap (hbar, HINST_COMMCTRL, IDB_TOOLBAR, 11, 0, 0);


		CommandBands_AddAdornments (g_hwndCB, g_hInst, 0, NULL);
		return g_hwndCB;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	static SHACTIVATEINFO s_sai;
	LPNMHDR hdr;
	int idctrl;
	
	
	switch (message)
	{
	case WM_CREATE:
		memset(&s_sai, 0, sizeof (s_sai));
		s_sai.cbSize = sizeof (s_sai);

#if 1		
		SHMENUBARINFO mbi;

		memset(&mbi, 0, sizeof(SHMENUBARINFO));
		mbi.cbSize     = sizeof(SHMENUBARINFO);
		mbi.hwndParent = hWnd;
		mbi.nToolBarId = IDR_MENU;
		mbi.hInstRes   = g_hInst;
		mbi.dwFlags=SHCMBF_HMENU|SHCMBF_HIDESIPBUTTON;

		if (!SHCreateMenuBar(&mbi)) 
		{
			g_hWndMenuBar = NULL;
		}
		else
		{
			g_hWndMenuBar = mbi.hwndMB;
		}
#endif		
		p_pmsplit=new PMSplitCtrl(hWnd,5);
		p_pmlv=new PMListView(hWnd);
		p_pmtc=new PMTabCtrl(hWnd);
		EnumInterfaces();
		break;
	case WM_SIZE:
		p_pmsplit->ReSize();
		p_pmlv->ReSize();
		p_pmtc->ReSize();
		return 0;
	case WM_LBUTTONDOWN:
		p_pmsplit->MouseDown(wParam,LOWORD(lParam),HIWORD(lParam));
		return 0;
	case WM_LBUTTONUP :
		p_pmsplit->MouseUp(wParam,LOWORD(lParam),HIWORD(lParam));
		return 0;
	case WM_MOUSEMOVE :
		p_pmsplit->MouseMove(wParam,LOWORD(lParam),HIWORD(lParam));
		return 0;
	case WM_NOTIFY:
		idctrl=(int)wParam;
		hdr=(LPNMHDR)lParam;
		if(hdr->hwndFrom==p_pmlv->g_hwnd)
			p_pmlv->Notify(idctrl, hdr);
		else if(hdr->hwndFrom==p_pmtc->g_hwnd)
		{
			PMControl * ctrl=p_pmtc;
			ctrl->Notify(idctrl, hdr);
		}
		break;
	case WM_DESTROY:
		delete p_pmlv;
		delete p_pmtc;
		CommandBar_Destroy(g_hWndMenuBar);
		PostQuitMessage(0);
		break;
	case WM_ACTIVATE:
		// Notify shell of our activate message
#if 0		
		if(LOWORD(wParam)==WA_INACTIVE)
		{
			DestroyWindow(hWnd);
			return 0;
		}
#endif
		SHHandleWMActivate(hWnd, wParam, lParam, &s_sai, FALSE);
		break;
	case WM_SETTINGCHANGE:
		SHHandleWMSettingChange(hWnd, wParam, lParam, &s_sai);
		break;
    case WM_COMMAND:
		int wmId, wmEvent;
		wmId    = LOWORD(wParam); 
		wmEvent = HIWORD(wParam); 
		// Parse the menu selections:
		switch (wmId)
		{
		case IDM_HELP_ABOUT:
                    DialogBox(g_hInst, (LPCTSTR)IDD_ABOUTBOX_WIDE, hWnd, About);
                    break;
		case IDM_HELP_SHUTDOWN:
                    DialogBox(g_hInst, (LPCTSTR)IDD_SYSTEMBOX, hWnd, DialogProcSystem);
                    break;
		case IDM_HELP_IR:
                    DialogBox(g_hInst, (LPCTSTR)IDD_IR, hWnd, DialogProcIR);
                    break;
		case IDM_HELP_CLK:
                    DialogBox(g_hInst, (LPCTSTR)IDD_CLOCKBOX, hWnd, DialogProcClock);
                    break;
		case IDM_HELP_PCLK:
                    DialogBox(g_hInst, (LPCTSTR)IDD_PCLOCKBOX, hWnd, DialogProcPClock);
                    break;
		case IDM_HELP_SCLK:
                    DialogBox(g_hInst, (LPCTSTR)IDD_SCLOCKBOX, hWnd, DialogProcSClock);
                    break;
		case IDM_HELP_GDI:
                    DialogBox(g_hInst, (LPCTSTR)IDD_GDI, hWnd, DialogProcGDI);
                    break;
		case IDM_HELP_SYS:
                    DialogBox(g_hInst, (LPCTSTR)IDD_GDI, hWnd, DialogProcSYS);
                    break;
		case IDM_HELP_LB:
                    DialogBox(g_hInst, (LPCTSTR)IDD_GDI, hWnd, DialogProcLB);
                    break;
		case IDM_HELP_CPU:
                    DialogBox(g_hInst, (LPCTSTR)IDD_GDI, hWnd, DialogProcCPU);
                    break;
		case IDM_EXIT:
                    SendMessage (hWnd, WM_CLOSE, 0, 0);				
                    break;
		default:
                    return DefWindowProc(hWnd, message, wParam, lParam);
            }
            break;		
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}
ATOM MyRegisterClass(HINSTANCE hInstance, LPTSTR szWindowClass)
{
	WNDCLASS wc;

	wc.style         = CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc   = WndProc;
	wc.cbClsExtra    = 0;
	wc.cbWndExtra    = 0;
	wc.hInstance     = hInstance;
	wc.hIcon         = 0;
	wc.hCursor       = 0;
	wc.hbrBackground = (HBRUSH) COLOR_WINDOW;
	wc.lpszMenuName  = 0;
	wc.lpszClassName = szWindowClass;

	return RegisterClass(&wc);
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
	HWND hWnd;
	TCHAR szTitle[]=L"PowerManager";		// title bar text
	TCHAR szWindowClass[]=L"DeviceInitialize";	// main window class name
	INITCOMMONCONTROLSEX iccex; 

	g_hInst = hInstance; // Store instance handle in our global variable


	// SHInitExtraControls should be called once during your application's initialization to initialize any
	// of the device specific controls such as CAPEDIT and SIPPREF.
	SHInitExtraControls();
	iccex.dwSize = sizeof (INITCOMMONCONTROLSEX);
	iccex.dwICC = ICC_BAR_CLASSES | ICC_COOL_CLASSES|ICC_TREEVIEW_CLASSES|ICC_TAB_CLASSES;

	InitCommonControlsEx (&iccex);

	g_ImgList=ImageList_Create(16,16,ILC_COLOR32|ILC_MASK,10,0);
	ImageList_AddIcon(g_ImgList,LoadIcon(g_hInst,MAKEINTRESOURCE(IDI_ICON1)));
	ImageList_AddIcon(g_ImgList,LoadIcon(g_hInst,MAKEINTRESOURCE(IDI_ICON2)));
	ImageList_AddIcon(g_ImgList,LoadIcon(g_hInst,MAKEINTRESOURCE(IDI_ICON3)));
	ImageList_AddIcon(g_ImgList,LoadIcon(g_hInst,MAKEINTRESOURCE(IDI_ICON4)));		
	ImageList_AddIcon(g_ImgList,LoadIcon(g_hInst,MAKEINTRESOURCE(IDI_ICON5)));
	ImageList_AddIcon(g_ImgList,LoadIcon(g_hInst,MAKEINTRESOURCE(IDI_ICON6)));	
	ImageList_AddIcon(g_ImgList,LoadIcon(g_hInst,MAKEINTRESOURCE(IDI_ICON7)));	
	
	hWnd = FindWindow(szWindowClass, szTitle);
	if (hWnd)
	{
		SetForegroundWindow((HWND)((ULONG) hWnd | 0x00000001));
		return 0;
	}

	if (!MyRegisterClass(hInstance, szWindowClass))
	{
		return FALSE;
	}

	hWnd = CreateWindow(szWindowClass, szTitle, WS_VISIBLE,
	                    CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);

	if (!hWnd)
	{
		return FALSE;
	}

	//SHFullScreen(hWnd, SHFS_HIDETASKBAR | SHFS_HIDESIPBUTTON | SHFS_HIDESTARTICON);
	//RECT rect;
	//SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, FALSE);	
	//MoveWindow(hWnd, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), FALSE);
	//MoveWindow(hWnd, rect.left, rect.top,rect.right-rect.left , rect.bottom-rect.top, FALSE);
	//CreateBar(hWnd);
	if (g_hWndMenuBar)
    {
        RECT rc;
        RECT rcMenuBar;

        GetWindowRect(hWnd, &rc);
        GetWindowRect(g_hWndMenuBar, &rcMenuBar);
        rc.bottom -= (rcMenuBar.bottom - rcMenuBar.top);
		
        MoveWindow(hWnd, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, FALSE);
    }
	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);

	return TRUE;
}
//------------------------------------------------------------------------------

int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow )
{
#if 0
	HANDLE h_mem;
	DWORD VirBase;
	TCHAR txt[512];

	h_mem = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 40960, _T("LCD_Framebuffer"));
	if (h_mem != NULL)
	{
		VirBase = (DWORD)MapViewOfFile(h_mem, FILE_MAP_WRITE, 0, 0, 0);
		wsprintf(txt,_T("CreateFileMapping 0x%08x"),VirBase);
		MessageBox(0, txt,_T("info"),MB_OK|MB_TOPMOST);
	}
	else
	{
		VirBase = NULL;
		MessageBox(0, TEXT("CreateFileMapping Failed\r\n"),_T("error"),MB_ICONEXCLAMATION|MB_TOPMOST);
		return 0;
	}

	//Windows memory allocation is page-demond,
	//at this time,there is no real physical memory allocated
	*(volatile DWORD *)VirBase=123;
	MessageBox(0, TEXT("memory write\r\n"),_T("info"),MB_OK|MB_TOPMOST);
	RETAILMSG(1,( TEXT("memory write\r\n")));


	if (!VirtualCopy((void *)VirBase, (void *)(0x30100000 >> 8), 40960, PAGE_READWRITE | PAGE_NOCACHE | PAGE_PHYSICAL))
	{
		MessageBox(0, TEXT("VirtualCopy Failed\r\n"),_T("error"),MB_ICONEXCLAMATION|MB_TOPMOST);
		return 0;
	}

	*(volatile DWORD *)(VirBase+0x200)=123;
	memset((void *)VirBase,0xae,0x4000);
	MessageBox(0, TEXT("memory write\r\n"),_T("info"),MB_OK|MB_TOPMOST);

	MessageBox(0, TEXT("memory physical mapping OK\r\n"),_T("info"),MB_OK|MB_TOPMOST);

	UnmapViewOfFile((LPVOID)VirBase);
	CloseHandle(h_mem);
#endif

	MSG msg;

	//g_taskbar=new PMTaskBar();

	// Perform application initialization:
	if (!InitInstance(hInstance, nCmdShow))
	{
		return FALSE;
	}
	// Main message loop:
	while (GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	if (g_hwndCB)
	{
		DestroyWindow (g_hwndCB);
	}

	//delete g_taskbar;

	return 0;
}

